var EmojoEasy = (function() {
    function _EmojoEasy(property) {
        if (!(this instanceof _EmojoEasy)) {
            throw '必须通过new关键字实例化!';
        }
        this.config = {
            style: {
                column: 8,
                row: -1,
                size: 24,
				ubiety: 'top-right' // top-center top-right bottom-center bottom-right
            },
			// 窗口大小变动策略
			resizeModel: 'redraw', // hide(隐藏) redraw(重绘)
            // 触发元素
            button: null,
            buttonId: null,
			buttonRect: {},
            // 面板
            panel: null,
            panelId: null,
			panelFlag: false, // 显示隐藏标记
            // 表情包集合
            emojis: {
                codes: ["&#128512;", "&#128513;", "&#128514;", "&#128515;", "&#128516;", "&#128517;",
                    "&#128518;", "&#128519;", "&#128520;", "&#128521;", "&#128522;", "&#128523;",
                    "&#128524;", "&#128525;", "&#128526;", "&#128527;", "&#128528;", "&#128529;",
                    "&#128530;", "&#128531;", "&#128532;", "&#128533;", "&#128534;", "&#128535;",
                    "&#128536;", "&#128537;", "&#128538;", "&#128539;", "&#128540;", "&#128541;",
                    "&#128542;", "&#128543;", "&#128544;", "&#128545;", "&#128546;", "&#128547;",
                    "&#128548;", "&#128549;", "&#128550;", "&#128551;", "&#128552;", "&#128553;",
                    "&#128554;", "&#128555;", "&#128556;", "&#128557;", "&#128558;", "&#128559;",
                    "&#128560;", "&#128561;", "&#128562;", "&#128563;", "&#128564;", "&#128565;",
                    "&#128566;", "&#128567;", "&#128568;", "&#128569;", "&#128570;", "&#128571;",
                    "&#128572;", "&#128573;", "&#128574;", "&#128575;", "&#128576;", "&#128577;",
                    "&#128578;", "&#128579;", "&#128580;", "&#128581;", "&#128582;", "&#128583;",
                    "&#128584;", "&#128585;", "&#128586;", "&#128587;", "&#128588;", "&#128589;",
                    "&#128590;", "&#128591;"
                ]
            },
			// 选择表情包的回调
			select(data) {}
        };
		// 需要二级逐个拷贝的节点
		const configChildNode = ['style'];
		// 挂载到this的节点
		const configThisNode = ['select', 'resize'];
		// 不允许配置的 KEY
		const configExcludes = ['button', 'panel', 'panelFlag', 'panelRect', 'emojis'];
		
        const that = this;
		const config = this.config;

        // 配置
        this.setConfig = function(option) {
            // 属性拷贝
            let keys = Object.keys(option);
			for (let key of keys) {
				let node = option[key];
				if (configExcludes.includes(key)) { // 排除节点
					continue;
				} else if (configThisNode.includes(key)) { // 挂载到this
					that[key] = node;
				} else if (configChildNode.includes(key)) { // 二级逐个拷贝
					if (typeof node !== 'object') throw '节点"' + key + '"不是对象类型';
					let nodeKeys = Object.keys(node);
					for (let nodeKey of nodeKeys) {
						config[key][nodeKey] = node[nodeKey];
					}
				} else { // 整个节点拷贝
					config[key] = node;
				}
			}
            // 点击监听
            config.button = document.getElementById(config.buttonId);
            config.button.addEventListener('click', that.random);
        };
		
		// 选择表情包事件
		this.select = function(data) {};
		
		// 显示面板
		this.show = function() {
			config.panel.style.display = 'block';
			config.panelFlag = true;
		};
		
		// 隐藏面板
		this.hide = function() {
			config.panel.style.display = 'none';
			config.panelFlag = false;
		};
		
		// 选择表情包事件
		this.select = function(param) {
			if (typeof param === 'function') that.select = param;
		};
		
		// 窗口大小变化事件
		this.resize = function(param) {
			if (typeof param === 'function') that.resize = param;
			if (!config.panel) return;
			if (config.resizeModel === 'redraw') {
				that.random();
			} else if (config.resizeModel === 'hide') {
				that.hide();
			}
		};
		
		// 生成面板
		function generatePanel() {
			let html = '', child = '';
			// 符号源表情包
			for (let i = 1; i <= config.emojis.codes.length; i++) {
			    let emoji = config.emojis.codes[i - 1];
			    child += '<div data-type="code" data-data="' + emoji.replace('&', '&amp;') + '">' + emoji + '</div>';
			    if (i % config.style.column === 0 || i === config.emojis.codes.length) {
			        html += '<div class="emojo-list-row">' + child + '</div>';
			        child = '';
			    }
			}
			
			let panel = document.createElement('div');
			config.panel = panel;
		
			// 生成面板ID
			config.panelId = 'emoji-panel-' + new Date().getTime();
			// 属性设置
			panel.id = config.panelId;
			panel.className = 'emojo-list emoji-no-select';
			panel.innerHTML = html;
			// 图标大小
			let size = config.style.size + (config.style.size / 2);
			// 面板样式
			panel.style.fontSize = config.style.size + 'px';
			panel.style.maxHeight = (config.style.row * size) + 'px';
			// 子元素宽高
			panel.querySelectorAll('.emojo-list-row>div').forEach(dom => {
				dom.style.width = size + 'px';
				dom.style.height = size + 'px';
				dom.style.lineHeight = size + 'px';
			});
			document.body.insertAdjacentElement('beforeend', panel);
			
			// 选择监听
			panel.querySelectorAll('.emojo-list-row>div').forEach(dom => {
			    dom.addEventListener('click', function() {
					let selection = window.getSelection();
			        // 回调
			        that.select({
						// 选择的emoji信息
			            emoji: {
							type: dom.getAttribute('data-type'),
							data: dom.getAttribute('data-data')
						},
						// 光标信息
						range: selection.rangeCount > 0 ? selection.getRangeAt(0) : {}
			        });
			    });
			});
			
			// 点击其他位置判断
			document.addEventListener('click', function(event) {
				if (event.target.id !== config.panelId &&
					event.target.id !== config.buttonId &&
					!config.panel.contains(event.target)) {
					that.hide();
				}
			});
		}

        // 渲染-表情包列表
        this.random = function() {
			if (!config.panel) {
				generatePanel();
			}
			that.show();
			
			// 位置计算
			let panel = config.panel;
			let rectButton = config.button.getBoundingClientRect();
			let rectPanel = panel.getBoundingClientRect();
			config.buttonRect = rectButton;
			
			let buttomCenterLine = rectButton.left + (rectButton.width / 2); // 按钮中心线，到左边的距离
			let xCenterLeft = buttomCenterLine - (rectPanel.width / 2); // x居中-left数值
			let yTopTop = rectButton.top - rectPanel.height; // y贴合顶部-top数值
			let yBottomTop = rectButton.top + rectButton.height; // y贴合底部-top数值
			if (config.style.ubiety === 'top-center') {
				panel.style.left = xCenterLeft + 'px';
				panel.style.top = yTopTop + 'px';
			} else if (config.style.ubiety === 'top-right') {
				panel.style.left = rectButton.left + 'px';
				panel.style.top = yTopTop + 'px';
			} else if (config.style.ubiety === 'bottom-center') {
				panel.style.left = xCenterLeft + 'px';
				panel.style.top = yBottomTop + 'px';
			} else if (config.style.ubiety === 'bottom-right') {
				panel.style.left = rectButton.left + 'px';
				panel.style.top = yBottomTop + 'px';
			}
        };
		
		// 触发元素坐标判断 true:变动 false:未变动
		function buttonXYJump() {
			let nowRect = config.button.getBoundingClientRect();
			return nowRect.x !== config.buttonRect.x || nowRect.y !== config.buttonRect.y;
		}

		(function() {
			// 配置初始化
			that.setConfig(property);
			// 窗口变化监听
			window.addEventListener('resize', function() {
				if (buttonXYJump()) {
					that.resize(); // 手动执行，这样该节点的函数可以被重写
				}
			});
			// 滚轮监听
			window.addEventListener('wheel', function() {
				if (!config.panelFlag) return;
				setTimeout(that.resize, 50);
				setTimeout(that.resize, 150);
				setTimeout(that.resize, 210);
			});
		})();
    }
    return _EmojoEasy;
})();